class Student:
  # 两边加上下划线（双下划线）的方法名被称为“特殊方法”或“魔术方法”。这些是 Python 语言本身为了实现特定功能而预留给开发者使用的方法。它们通常会被 Python 的内置函数或语法糖所隐式调用。例如，当你打印一个对象时，Python 实际上是调用了该对象的 __repr__ 或 __str__ 方法（取决于上下文）
  def __init__(self, name,grade, age): # self 是一个约定俗成的名字，用来指代类的实例（即对象）。当你创建了 Student 类的一个实例后，任何属于这个实例的方法调用都会自动将该实例作为第一个参数传递给方法。因此，self 参数允许你访问实例的属性和其他方法
    # 这个方法是在创建新实例时自动调用的构造函数。它初始化对象的状态
    self.name = name
    self.grade = grade
    self.age = age
  def __repr__(self): # __repr__ 是 Python 中的一个特殊方法，它应该返回一个对象的“官方”字符串表示形式，理想情况下，这个字符串应该是可以被 Python 解释器执行以重新创建该对象的表达式。repr() 内置函数会调用这个方法来获取对象的字符串表示
    return repr((self.name, self.grade, self.age)) # repr() 是 Python 的内置函数。它用于获取一个对象的“官方”字符串表示，通常这个字符串是可以被 Python 解释器执行以重新创建该对象的表达式（尽管这不是必需的）。repr() 函数调用对象的 __repr__ 方法来获取这个字符串表示
student_objects=[
  Student('Alice', 'A', 15),
  Student('Bob', 'B', 12),
  Student('Charlie', 'C', 10)
]
print(student_objects[0])
print(student_objects)

Student.__lt__ = lambda self, other: self.age < other.age # 这行代码动态地为 Student 类添加了一个 __lt__（小于）方法。在 Python 中，类是可变的，这意味着你可以在定义类之后为其添加属性或方法。这里使用的是一个匿名函数（lambda），它接收两个参数 self 和 other，并比较这两个 Student 实例的 age 属性，如果 self 的年龄小于 other 的年龄，则返回 True，否则返回 False。
print(sorted(student_objects)) # 调用了内置的 sorted() 函数，并将 student_objects 列表作为参数传递给它。由于我们在上一步中已经为 Student 类添加了 __lt__ 方法，sorted() 函数现在可以比较 Student 对象，并根据它们的 age 属性进行排序。结果是一个新的列表，其中包含按年龄升序排列的学生对象
print(sorted(student_objects, key=lambda student: student.grade, reverse=False)) # 再次调用 sorted() 函数，但是这次提供了额外的参数：
# key 参数指定了一种提取排序键的方式。在这个例子中，key 是一个 lambda 函数，它接收一个 Student 对象并返回其 grade 属性作为排序依据。
# reverse 参数设置为 False 表示我们希望得到的结果是升序的。默认情况下，reverse 也是 False，所以即使不明确指定，也会得到相同的结果。如果你想得到降序结果，你可以将 reverse 设置为 True。